/*******************************************************************************
SpriteKit.h

	Author:		LiuDingXi
	e-mail:		liudx@gmail.com
	Date time:	2009-08-06

	Copyright (C) 2009
	All rights reserved.
	
*******************************************************************************/

#ifndef _SPRITEKIT_H_
#define _SPRITEKIT_H_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#include "ximage.h"
#include "BaseParser.h"

class CSpriteKit : public CBaseParser
{
public:
	CSpriteKit();
	virtual ~CSpriteKit();

public:
	BOOL	Load(CArchive& ar);
	BOOL	Store(CArchive& ar);

	BOOL	Free();

public:
	struct GROUP;
	struct IMAGE
	{
		CString szName;
		CxImage	xImage;
		RECT	rect;		// for image view
		GROUP*	pGroup;

		short	nType;
		short	nStyle;		// style id

		int		x;
		int		y;
		union{
			int		cx;
			int		x2;
			int		r;
		};
		union{
			int		cy;
			int		y2;
			int		r2;
			int		angles;		// hi_word is Begin Angle, lo_word is End Angle, angle = [0-360]
		};

		SceneDat::STYLE style;
		
		SceneDat::INT idx;
		SceneDat::PTR ptr;
	};

	struct GROUP
	{
		CString szName;
		CString szPath;

		RECT rect;
		BOOL bExpand;
		
		list<IMAGE*> ImgList;

		void AddImage(LPCTSTR p, LPCTSTR szFolder);
		void AddDraw(LPCTSTR p);
	};

	list<GROUP*>	m_Groups;

	GROUP* NewGroup(LPCTSTR p);

	enum DTYPE{tSprite, tAction, tFrame, tFclip};
	struct TDATA
	{
		UINT nType;
		virtual void OnDraw(CDC* pDC, int x, int y, int zoom) = 0;
		virtual void OnDraw2(CDC* pDC, int x, int y, int cx, int cy) = 0;
	};

	struct FCLIP : public TDATA
	{
		FCLIP(){nType=tFclip;}
		~FCLIP();

		CString szName;
		CString szGroup;
		CString szImage;
		
		int nPosX;
		int nPosY;
		int nXRep;	// x repete
		int nYRep;	// y repete
		int nOffX;	// x offset
		int nOffY;	// y offset

		SceneDat::PTR ptr;

		BOOL bLock;

		IMAGE* pImage;

		float	fAngle;
		CxImage* pTrans;

		void Transfer();

		SIZE GetSize()const;
		void GetRect(RECT& rect)const;
		bool HitTest(int x, int y)const;
		CxImage* GetImage()const;

		void OnDraw(CDC* pDC, int x, int y, int zoom);
		void OnDraw2(CDC* pDC, int x, int y, int cx, int cy);

		void DrawPoint(CDC* pDC, int x, int y, int zoom);
		void DrawLine(CDC* pDC, int x, int y, int zoom);
		void DrawRect(CDC* pDC, int x, int y, int zoom);
		void DrawRbox(CDC* pDC, int x, int y, int zoom);
		void DrawEllipse(CDC* pDC, int x, int y, int zoom);
		void DrawCircle(CDC* pDC, int x, int y, int zoom);
		void DrawArc(CDC* pDC, int x, int y, int zoom);
		void DrawText(CDC* pDC, int x, int y, int zoom);

		CString GetFclip();
	};
	struct FRAME : public TDATA
	{
		FRAME(){nType=tFrame;}
		CString szName;
		list<FCLIP*> FclipList;

		FCLIP* AddFclip(LPCTSTR p);
		bool DelFclip(FCLIP* pFclip);
		void Delete();

		void OnDraw(CDC* pDC, int x, int y, int zoom);
		void OnDraw2(CDC* pDC, int x, int y, int cx, int cy);
		bool HitTest(int x, int y)const;
		void GetRect(RECT& rect)const;

		void Offset(int x, int y);
		void FlipY();

		CString GetFrame();
		void ApplyDelay(bool checkSame);

		int	nDelay;

		SceneDat::PTR ptr;
	};
	struct ACTION : public TDATA
	{
	protected:
		int nActive;
	public:
		ACTION(){nType=tAction; nActive=0;}
		CString szName;

		UINT nFlags;
		
		list<FRAME*> FrameList;

		FRAME* AddFrame(LPCTSTR p);
		bool DelFrame(FRAME* pFrame);
		void Delete();
		
		void OnDraw(CDC* pDC, int x, int y, int zoom);
		void OnDraw2(CDC* pDC, int x, int y, int cx, int cy);

		void OnUpdate();
		bool HitTest(int x, int y)const;
		void GetRect(RECT& rect)const;

		FRAME* GetFrame(int nIndex)const;

		CString GetAction();

		SceneDat::PTR ptr;
		SceneDat::INT idx;
	};

	struct SPRITE : public TDATA
	{
	protected:
		int nActive;
	public:
		SPRITE(){nType=tSprite; nActive=0;}
		CString szName;

		UINT nFlags;
		
		list<ACTION*> ActionList;

		ACTION* AddAction(LPCTSTR p);
		bool DelAction(ACTION* pAction);
		void Delete();
		
		void OnDraw(CDC* pDC, int x, int y, int zoom);
		void OnDraw2(CDC* pDC, int x, int y, int cx, int cy);

		void OnUpdate();
		bool HitTest(int x, int y)const;
		void GetRect(RECT& rect)const;

		ACTION* GetAction(int nIndex)const;

		CString GetSprite();

		SceneDat::PTR ptr;
		SceneDat::INT idx;
	};


	list<SPRITE*> m_Sprites;

	SPRITE* NewSprite(LPCTSTR p);
	bool DelSprite(SPRITE* pSprite);

	BOOL LinkImage(FCLIP* pFclip);
	
public:

	SPRITE* FindSprite(LPCTSTR szName);

	void	GetImages(set<IMAGE*>& ImgSet);

	int		JoinTo(list<IMAGE*>& refList);
	int		JoinTo(list<FCLIP*>& refList);
	int		JoinTo(list<FRAME*>& refList);
	int		JoinTo(list<ACTION*>& refList);
	int		JoinTo(list<SPRITE*>& refList);
};


#endif//_SPRITEKIT_H_
